package com.auxgroup.hr.front.site.co.performance;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.auxgroup.hr.front.site.inteceptor.SessionGain;
import com.auxgroup.hr.front.site.vo.performance.AssessPersRespVO;
import com.auxgroup.hr.front.site.vo.performance.PerformanceReqVO;
import com.auxgroup.hr.front.site.vo.performance.PerformanceResultApproveRespVO;
import com.auxgroup.hr.front.site.vo.performance.PerformanceResultSaveReqVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.auxgroup.hr.front.commons.BaseRetCode;
import com.auxgroup.hr.front.commons.utils.WebServiceClient;
import com.auxgroup.hr.front.commons.utils.WebServiceUtils;
import com.auxgroup.hr.front.commons.vo.BaseResponseVO;
import com.auxgroup.hr.front.commons.vo.UserDTO;
import com.auxgroup.hr.front.dao.domain.PsCEpAppHdr;
import com.auxgroup.hr.front.dao.domain.PsCEpDocVw;
import com.auxgroup.hr.front.dao.domain.PsCEpDocVwPrimary;
import com.auxgroup.hr.front.dao.domain.PsCEpEvaDocDv;
import com.auxgroup.hr.front.dao.domain.PsCEpMdlgradeV;
import com.auxgroup.hr.front.dao.repository.PsCEpEvaDocDvRepository;
import com.auxgroup.hr.front.dozer.IObjectMapper;
import com.auxgroup.hr.front.service.performance.PerformancePlanService;
import com.auxgroup.hr.front.service.performance.PerformanceResultService;
import com.auxgroup.hr.front.service.process.ProcessService;
import com.auxgroup.hr.front.site.co.BaseCO;
import com.auxgroup.hr.front.site.inteceptor.SessionGain;
import com.auxgroup.hr.front.site.vo.performance.AssessPersRespVO;
import com.auxgroup.hr.front.site.vo.performance.PerformanceReqVO;
import com.auxgroup.hr.front.site.vo.performance.PerformanceResultApproveRespVO;
import com.auxgroup.hr.front.site.vo.performance.PerformanceResultSaveReqVO;
import com.auxgroup.hr.front.ws.SoapXmlBuild;

/**
 * 绩效结果审批
 * @author lv-PC
 *
 */
@RestController
@RequestMapping("${auxgroup.hr.contextPath}/perresultapprove")
public class PerformanceResultApproveCO extends BaseCO {

	@Autowired
	private PerformanceResultService  performanceResultService;
	
	@Autowired
	private PerformancePlanService  performancePlanService;
	
	@Autowired
	private PsCEpEvaDocDvRepository psCEpEvaDocDvRepository;
	
	@Autowired
	private ProcessService processService;
	
	@Resource(name = "dozerMapper")
	protected IObjectMapper objectMapper;
	
	
	@Value("${ws.processService.approve.address}")
	private String processURL;
	
	@Value("${ws.processService.rankWs.soapAction}")
	private String rankWsSoapAction;
	
	@Value("${ws.processService.epWfWs.soapAction}")
	private String epWfWsSoapAction;
	
	/**
	 * 查询绩效结果审批人员列表
	 * @param cTransactionNbr
	 * @param user
	 * @return
	 */
	@GetMapping("/persons")
	public BaseResponseVO getPersons(String cTransactionNbr,String queryKey,@SessionGain("user") UserDTO user){
		logger.info("performance result getPersons param:{}",cTransactionNbr);
		if(StringUtils.isBlank(cTransactionNbr)){
			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
		}
		List<PsCEpDocVw> epdocs = performancePlanService.getepdocs(user.getOprId(), cTransactionNbr,queryKey,new Sort(Direction.ASC, "cEpRanking"));
		//排序
		sortList(epdocs);
		if(epdocs!=null&&!epdocs.isEmpty()){
			Map<String, String> per;
			List<Map<String, String>> pers = new ArrayList<Map<String,String>>();
			AssessPersRespVO respVO = new AssessPersRespVO();
			respVO.setTitle(epdocs.get(0).getText254());
			NumberFormat formater = new DecimalFormat("0.00");
			for (PsCEpDocVw epdoc : epdocs) {
				per = new HashMap<String, String>();
				per.put("name", epdoc.getName());
				per.put("emplid", epdoc.getEmplid());
				per.put("dept", epdoc.getDeptDescr());
				per.put("jobDescr", epdoc.getJobcodeDescr());
				per.put("docid", epdoc.getcEpAppraisalId());
				per.put("version", String.valueOf(epdoc.getVersion()));
				per.put("epPhase", epdoc.getcEpPhase());
				per.put("seqnbr", epdoc.getSeqnbr()==null?"":epdoc.getSeqnbr().toString());
				if("A".equals(epdoc.getcEvaType())){
					if(epdoc.getcEpScoreRevised()!=null){
						per.put("score",formater.format(epdoc.getcEpScoreRevised().doubleValue()));
					}else{
						per.put("score", "");
					}
				}
				if("B".equals(epdoc.getcEvaType())){
					per.put("score", epdoc.getcEpGradeRevised());
				}
				per.put("ranking", epdoc.getcEpRanking());
				pers.add(per);
			}
			respVO.setPers(pers);
			return buildRespone(respVO,false);
		}
		return buildRespone();
	}
	
	
	/**
	 * 对结果进行排序
	 * @param epdocs
	 */
	private void sortList(List<PsCEpDocVw> epdocs){
		Collections.sort(epdocs, new Comparator<PsCEpDocVw>() {
            @Override
            public int compare(PsCEpDocVw o1, PsCEpDocVw o2) {
            	int o1Int = 0;
            	int o2Int = 0;
            	if(StringUtils.isNotBlank(o1.getcEpRanking())){
            		String[] rank = o1.getcEpRanking().split("/");
            		if(rank!=null&&rank.length>0){
            			o1Int = Integer.valueOf(rank[0]);
            		}
            	}
            	if(StringUtils.isNotBlank(o2.getcEpRanking())){
            		String[] rank = o2.getcEpRanking().split("/");
            		if(rank!=null&&rank.length>0){
            			o2Int = Integer.valueOf(rank[0]);
            		}
            	}
                return o1Int - o2Int;
            }
        });
	}
	
	/**
	 * 绩效结果审批页信息
	 * @param reqVo
	 * @param user
	 * @return
	 */
	@GetMapping("/getHdrInfo")
	public BaseResponseVO getHdrInfo(PerformanceReqVO reqVo, @SessionGain("user") UserDTO user){
		//获取绩效结果审批头表
		PsCEpDocVwPrimary primary = new PsCEpDocVwPrimary();
		primary.setcEpAppraisalId(reqVo.getDocid());
		primary.setcTransactionNbr(reqVo.getcTransactionNbr());
		primary.setcWfType(reqVo.getWfType());
		primary.setOprid(user.getOprId());
		primary.setVersion(new BigDecimal(reqVo.getVersion()));
		primary.setSeqnbr(new BigDecimal(reqVo.getSeqnbr()));
		primary.setcEpPhase(reqVo.getEpPhase());
		PsCEpDocVw docVw = performancePlanService.getepdoc(primary);
		if(docVw==null){
			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
		}
		PsCEpAppHdr appHdr = performanceResultService.getAppHdr(reqVo.getDocid(), new BigDecimal(reqVo.getVersion()));
		if(appHdr==null){
			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
		}
		NumberFormat formater = new DecimalFormat("0.00");
		PerformanceResultApproveRespVO respVo = new PerformanceResultApproveRespVO();
		respVo.setDept(docVw.getDeptDescr());
		respVo.setEmplid(docVw.getEmplid());
		respVo.setJodDescr(docVw.getJobcodeDescr());
		respVo.setName(docVw.getName());
		respVo.setEvaType(docVw.getcEvaType());
		respVo.setEvaModel(docVw.getcEvaModel());
		respVo.setRanking(appHdr.getcEpRanking());
		respVo.setScore(formater.format(appHdr.getcEpScore().doubleValue()));
		respVo.setScoreRevised(formater.format(appHdr.getcEpScoreRevised().doubleValue()));
		respVo.setLevel(appHdr.getcEpGrade());
		respVo.setLevelRevised(appHdr.getcEpGradeRevised());
		respVo.setRatio(formater.format(appHdr.getcEvaRate().doubleValue()));
		respVo.setRatioRevised(formater.format(appHdr.getcEvaRateRevised().doubleValue()));
		respVo.setComments(appHdr.getcEpAdjReason());
		respVo.setLevelSelects(buildModelSelects(docVw.getcEvaModel()));
		return buildRespone(respVo,false);
	}
	
	
	
	private List<Map<String, Object>> buildModelSelects(String evaModel){
		//添加选项信息
		List<PsCEpEvaDocDv> evaDocs = psCEpEvaDocDvRepository.findAllByEvaModel(evaModel);
		List<Map<String, Object>> selects = new ArrayList<Map<String,Object>>();
		if(evaDocs!=null&&!evaDocs.isEmpty()){
			Map<String, Object> select;
			for (PsCEpEvaDocDv doc : evaDocs) {
				select = new HashMap<String, Object>();
				select.put("key", doc.getCEvaGrade());
				select.put("value", doc.getCEvaGrade());
				selects.add(select);
			}
		}
		return selects;
	}
	
	
	/**
	 * 系数获取
	 * @param evaModel
	 * @param level
	 * @param user
	 * @return
	 */
	@GetMapping("/getRate")
	public BaseResponseVO getRate(String evaModel,String levelRevised,@SessionGain("user") UserDTO user){
		PsCEpMdlgradeV rate = performanceResultService.getMdlGrade(evaModel, levelRevised);
		if(rate!=null){
			return buildRespone(rate.getcEvaRate(),false);
		}
		return buildRespone();
	}
	
	
	/**
	 * 保存绩效结果审批
	 * @param reqVo
	 * @param user
	 * @return
	 */
	@PostMapping("/saveResult")
	public BaseResponseVO saveResult(PerformanceResultSaveReqVO reqVo, @SessionGain("user") UserDTO user){
		PsCEpAppHdr appHdr = performanceResultService.getAppHdr(reqVo.getDocid(), new BigDecimal(reqVo.getVersion()));
		if(appHdr==null){
			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
		}
		if(reqVo.getScoreRevised()!=null){
			appHdr.setcEpScoreRevised(reqVo.getScoreRevised());
		}
		if(reqVo.getLevelRevised()!=null){
			appHdr.setcEpGradeRevised(reqVo.getLevelRevised());
		}
		if(reqVo.getRatioRevised()!=null){
			appHdr.setcEvaRateRevised(reqVo.getRatioRevised());
		}
		if(reqVo.getComments()!=null){
			appHdr.setcEpAdjReason(reqVo.getComments());
		}
		performanceResultService.saveAppHdr(appHdr);
		StringBuilder soapXml = new StringBuilder();
		SoapXmlBuild.buildRankRequest(soapXml, appHdr.getcEpProgramId(), appHdr.getcEpCalendarId(), 
				appHdr.getcEpPeriodId(), appHdr.getcEpRankGroup(), appHdr.getcEvaType());
		String responXml = WebServiceClient.doPostSoap(processURL, soapXml.toString(), rankWsSoapAction);
		WebServiceUtils.handleRankWSRespXml(responXml, "C_RANK_RES");
		return buildRespone();
	}
	
	
	
	/**
	 * 提交绩效结果审批
	 * @param reqVo
	 * @param user
	 * @return
	 */
	@PostMapping("/commitResult")
	public BaseResponseVO commitResult(String cTransactionNbr,@SessionGain("user") UserDTO user){
		List<PsCEpDocVw> epdocs = performancePlanService.getepdocs(user.getOprId(), cTransactionNbr,"",new Sort(Direction.ASC, "cEpRanking"));
		if(epdocs==null||epdocs.isEmpty()){
			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
		}
		PsCEpDocVw docVw = epdocs.get(0);
		StringBuilder soapXml = new StringBuilder();
		SoapXmlBuild.buildWfWsRequest(soapXml, docVw.getcEpProgramId(), docVw.getcEpTemplate(), 
				docVw.getcEpCalendarId(), docVw.getcEpPeriodId(), docVw.getcEpRankGroup(), docVw.getcEpMethod(), docVw.getEmplid2());
		String responXml = WebServiceClient.doPostSoap(processURL, soapXml.toString(), epWfWsSoapAction);
		Map<String, String> result = WebServiceUtils.handleWfWSRespXml(responXml, "C_EP_WF_RES");
		if(result!=null&&result.containsKey("MESSAGE_TEXT")){
			if("成功".equals(result.get("MESSAGE_TEXT"))){
				return buildRespone();
			}else{
				return buildRespone(BaseRetCode.CODE_ERROR_SYS.getRetCode(), result.get("MESSAGE_TEXT"));
			}
		}
		return buildRespone(BaseRetCode.CODE_ERROR_SYS);
	}
}
